﻿using System;
using Tinter.Application.Modules.Finance.DTOs;
using Tinter.Common.Pagination;

namespace Tinter.Application.Modules.Finance.Services
{
    /// <summary>
    /// This is the contract that the application will interact to perform various operations for "finance management".
    /// The responsability of this contract is oschestrate operations, check security, cache,
    /// adapt entities to DTO etc.
    /// </summary>
    public interface IFinanceAppService
    {
        /// <summary>
        /// Add new expense project.
        /// </summary>
        /// <param name="dtoMyExpenseProject">The expense project information</param>
        /// <returns>Added expense representation</returns>
        MyExpenseProjectDto AddExpenseProject(MyExpenseProjectDto dtoMyExpenseProject);

        /// <summary>
        /// Add new expense. 
        /// </summary>
        /// <param name="dtoMyExpense">The expense information</param>
        /// <returns>Added expense representation</returns>
        MyExpenseDto AddExpense(MyExpenseDto dtoMyExpense);

        /// <summary>
        /// Update existing expense.
        /// </summary>
        /// <param name="dtoMyExpense">The expense with changes</param>
        void UpdateExpense(MyExpenseDto dtoMyExpense);

        /// <summary>
        /// Remove existing expense.
        /// </summary>
        /// <param name="expenseId">The expense identifier</param>
        void RemoveExpense(int expenseId);

        /// <summary>
        /// Get expense by ID.
        /// </summary>
        /// <param name="expenseId">The expense identifier</param>
        /// <returns>Selected expense representation if exist or null if not exist</returns>
        MyExpenseDto GetExpense(int expenseId);

        /// <summary>
        /// Get user's paged expense projects.
        /// </summary>
        /// <param name="userId">The user identifier</param>
        /// <param name="pageNumber">One-based index of page</param>
        /// <param name="pageSize">The # of elements in each page</param>
        /// <returns>A collection of expense project representation</returns>
        PagedItems<MyExpenseProjectDto> GetExpenseProjects(Guid userId, int pageNumber, int pageSize);

        /// <summary>
        /// Get user's paged expenses in a specified date range.
        /// </summary>
        /// <param name="userId">The user identifier</param>
        /// <param name="fromUtc">The beginning of the range</param>
        /// <param name="toUtc">The end of the range</param>
        /// <param name="pageNumber">One-based index of page</param>
        /// <param name="pageSize">The # of elements in each page</param>
        /// <returns>A collection of expense representation</returns>
        PagedItems<MyExpenseDto> GetExpensesByRange(Guid userId, DateTime fromUtc, DateTime toUtc, int pageNumber, int pageSize);

        /// <summary>
        /// Get user's paged expenses in a specified user project.
        /// </summary>
        /// <param name="projectId">The project identifier</param>
        /// <param name="pageNumber">One-based index of page</param>
        /// <param name="pageSize">The # of elements in each page</param>
        /// <returns>A collection of expense representation</returns>
        PagedItems<MyExpenseDto> GetExpensesByProject(Guid projectId, int pageNumber, int pageSize);

        /// <summary>
        /// Find user's paged expenses with specific text in name or description.
        /// </summary>
        /// <param name="userId">The user identifier</param>
        /// <param name="text">The text to seach</param>
        /// <param name="pageNumber">One-based index of page</param>
        /// <param name="pageSize">The # of elements in each page</param>
        /// <returns>A collection of expense representation</returns>
        PagedItems<MyExpenseDto> FindExpenses(Guid userId, string text, int pageNumber, int pageSize);
    }
}
